package com.sunlee.admin.api.module.oss.controller;

import com.google.gson.Gson;
import com.sunlee.admin.api.annotation.LogOperation;
import com.sunlee.admin.api.module.oss.cloud.CloudStorageConfig;
import com.sunlee.admin.api.module.oss.cloud.OssFactory;
import com.sunlee.admin.api.module.oss.entity.SysOssEntity;
import com.sunlee.admin.api.module.oss.group.AliyunGroup;
import com.sunlee.admin.api.module.oss.group.QcloudGroup;
import com.sunlee.admin.api.module.oss.group.QiniuGroup;
import com.sunlee.admin.api.module.oss.service.SysOssService;
import com.sunlee.admin.api.module.sys.service.SysParamsService;
import com.sunlee.admin.api.util.FileUtil;
import com.sunlee.common.core.constant.Constant;
import com.sunlee.common.core.entity.PageData;
import com.sunlee.common.core.entity.Result;
import com.sunlee.common.core.enums.ErrorCodeEnum;
import com.sunlee.common.core.validator.ValidatorUtils;
import io.github.artislong.model.OssInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import java.util.*;

/**
 * 文件上传
 *
 * @author sunlee
 */
@Slf4j
@RestController
@RequestMapping("sys/oss")
@Api(tags = "文件上传")
public class SysOssController {

    @Autowired
    private SysOssService sysOssService;

    @Autowired
    private SysParamsService sysParamsService;

    @GetMapping("page")
    @ApiOperation(value = "分页")
    @RequiresPermissions("sys:oss:all")
    public Result<PageData<SysOssEntity>> page(@ApiIgnore @RequestParam Map<String, Object> params) {

        return Result.ok(sysOssService.page(params));
    }

    @GetMapping("info")
    @ApiOperation(value = "云存储配置信息")
    @RequiresPermissions("sys:oss:all")
    public Result<CloudStorageConfig> info() {
        CloudStorageConfig config = sysParamsService.getValueObject(Constant.CLOUD_STORAGE_CONFIG_KEY, CloudStorageConfig.class);

        return Result.ok(config);
    }

    @PostMapping
    @ApiOperation(value = "保存云存储配置信息")
    @LogOperation("保存云存储配置信息")
    @RequiresPermissions("sys:oss:all")
    public Result<Object> saveConfig(@RequestBody CloudStorageConfig config) {
        //校验类型
        ValidatorUtils.validateEntity(config);

        if (config.getType() == Constant.CloudService.QINIU.getValue()) {
            //校验七牛数据
            ValidatorUtils.validateEntity(config, QiniuGroup.class);
        } else if (config.getType() == Constant.CloudService.ALIYUN.getValue()) {
            //校验阿里云数据
            ValidatorUtils.validateEntity(config, AliyunGroup.class);
        } else if (config.getType() == Constant.CloudService.QCLOUD.getValue()) {
            //校验腾讯云数据
            ValidatorUtils.validateEntity(config, QcloudGroup.class);
        }
        sysParamsService.updateValueByCode(Constant.CLOUD_STORAGE_CONFIG_KEY, new Gson().toJson(config));
        // 保存后更新oss客户端
        OssFactory.updateClient();
        return Result.ok();
    }


    @PostMapping("upload")
    @ApiOperation(value = "上传文件")
    @RequiresPermissions("sys:oss:all")
    public Result<Map<String, Object>> upload(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            return Result.error(ErrorCodeEnum.UPLOAD_FILE_EMPTY);
        }

        //处理文件路径
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        String extension = FilenameUtils.getExtension(originalFilename);
        String filePath = FileUtil.getPathByDate("", extension);

        //上传文件
        OssInfo ossInfo = OssFactory.client().upLoad(file.getInputStream(), filePath);

        //记录上传文件
        SysOssEntity ossEntity = new SysOssEntity();
        ossEntity.setName(originalFilename);
        ossEntity.setFileType(extension);
        ossEntity.setUrl(ossInfo.getPath() + Constant.SYMBOL_SLASH + ossInfo.getName());
        ossEntity.setCreateDate(new Date());
        ossEntity.setType(OssFactory.client().getConfig().getType());
        sysOssService.insertOwn(ossEntity);

        Map<String, Object> data = new HashMap<>(2);
        data.put("src", ossEntity.getUrl());

        return Result.ok(data);
    }

    @DeleteMapping
    @ApiOperation(value = "删除")
    @LogOperation("删除")
    @RequiresPermissions("sys:oss:all")
    public Result<Object> delete(@RequestBody Long[] ids) {

        List<SysOssEntity> sysOssEntities = sysOssService.selectByIdsOwn(Arrays.asList(ids));

        // 收集云存储删除成功的id
        List<Long> delIds = new ArrayList<>();
        // 当前配置的云存储类型
        Integer currType = OssFactory.client().getConfig().getType();
        for (SysOssEntity item : sysOssEntities) {
            // 过滤云存储类型
            if (!item.getType().equals(currType)) {
                continue;
            }
            // 删除
            try {
                OssFactory.client().delete(item.getUrl());
            } catch (Exception e) {
                continue;
            }
            // 校验是否删除成功
            if (OssFactory.client().isExist(item.getUrl())) {
                continue;
            }
            // 删除成功
            delIds.add(item.getId());
        }

        if (CollectionUtils.isEmpty(delIds)) {
            return Result.error(ErrorCodeEnum.DELETE_WRONG.format(""));
        }

        boolean delRes = sysOssService.deleteBatchIdsOwn(delIds);

        if (!delRes) {
            String errorMsg = "云存储删除成功，但数据库删除失败=" + delIds;
            log.error(errorMsg);
            return Result.error(errorMsg);
        }
        return Result.ok();
    }

}